package com.liyuxiang.yygh.order.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.liyuxiang.yygh.enums.PaymentTypeEnum;
import com.liyuxiang.yygh.enums.RefundStatusEnum;
import com.liyuxiang.yygh.model.order.OrderInfo;
import com.liyuxiang.yygh.model.order.PaymentInfo;
import com.liyuxiang.yygh.model.order.RefundInfo;
import com.liyuxiang.yygh.order.service.OrderService;
import com.liyuxiang.yygh.order.service.PaymentService;
import com.liyuxiang.yygh.order.service.RefundInfoService;
import com.liyuxiang.yygh.order.service.AlipayService;
import com.liyuxiang.yygh.order.utils.ConstantPropertiesUtils;
import com.liyuxiang.yygh.order.utils.MyAlipayClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class AlipayServiceImpl implements AlipayService {
    @Autowired
    OrderService orderService;
    @Autowired
    PaymentService paymentService;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    RefundInfoService refundInfoService;

    /**
     * 生成支付宝支付二维码
     *
     * @param orderId
     * @return
     */
    @Override
    public Map<String, Object> createNative(Long orderId) {
        Map<String, Object> payMap = (Map) redisTemplate.opsForValue().get("payInfo-" + orderId.toString());
        if (payMap != null) {
            return payMap;
        }
        OrderInfo order = orderService.getOrderById(orderId);
        //向支付记录表中添加支付信息
        paymentService.savePaymentInfo(order, PaymentTypeEnum.ALIPAY.getStatus());
        //设置参数，调用支付宝生成二维码接口
        AlipayClient alipayClient = new MyAlipayClient();
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        request.setNotifyUrl(ConstantPropertiesUtils.NOTIFY_URL);//支付回调
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", order.getOutTradeNo());//设置你的订单号
        bizContent.put("total_amount", 0.01);//设置金额
        bizContent.put("subject", "测试");//设置标题名称
        bizContent.put("scene", "bar_code");
        request.setBizContent(bizContent.toString());
        //发起请求获取响应信息
        AlipayTradePrecreateResponse response = null;
        try {
            response = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
        Map<String, Object> result = new HashMap<>();
        result.put("orderId", orderId);
        result.put("totalFee", order.getAmount());
        result.put("resultCode", response.getCode());
        result.put("codeUrl", response.getQrCode());
        if (response.getCode() != null) {
            redisTemplate.opsForValue().set("payInfo-" + orderId.toString(), result, 120, TimeUnit.MINUTES);
        }
        return result;
    }

    @Override
    public String payCallback(HttpServletRequest request, HttpServletResponse response) {
        Map<String, String> params = new HashMap<>();
        //从支付宝回调的request域中取值
        Map<String, String[]> requestParams = request.getParameterMap();

        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = iter.next();
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            // 乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
            try {
                valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
            params.put(name, valueStr);
        }
        Map<String, String[]> parameterMap = request.getParameterMap();
        //商品订单号
        //String out_trade_no = request.getParameter("out_trade_no");   // 商户订单号
        // 当前交易状态
        String tradeStatus = request.getParameter("trade_status");   //交易状态
        //3.签名验证(对支付宝返回的数据验证，确定是支付宝返回的)
//        boolean signVerified = false;
//        try {
//            //3.1调用SDK验证签名
//            signVerified = AlipaySignature.rsaCheckV1(params, ConstantPropertiesUtils.PUBLIC_KEY, "UTF-8", ConstantPropertiesUtils.SIGN_TYPE);
//        } catch (AlipayApiException e) {
//            e.printStackTrace();
//        }
        //对验签进行处理
//        if (signVerified) {
//            //验签通过
//            if (tradeStatus.equals("TRADE_SUCCESS")) {
//                //支付成功后的业务处理
//                paymentService.paySuccess(parameterMap);
//                return "success";
//            }
//        } else { //验签不通过
//            System.err.println("验签失败");
//            return "failure";
//        }
        //不验签
        if (tradeStatus.equals("TRADE_SUCCESS")) {
            //支付成功后的业务处理
            paymentService.paySuccess(params);
            return "success";
        }
        return "failure";
    }

    @Override
    public Map<String, Object> queryPayStatus(Long orderId) {
        try {
            AlipayClient alipayClient = new MyAlipayClient();
            AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
            OrderInfo orderInfo = orderService.getOrderById(orderId);
            JSONObject bizContent = new JSONObject();
            bizContent.put("out_trade_no", orderInfo.getOutTradeNo());//设置你的订单号
            request.setBizContent(bizContent.toString());
            AlipayTradeQueryResponse response = alipayClient.execute(request);
            System.out.println(response.toString());
            String status = response.getTradeStatus();//获取订单的状态
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("trade_state", status);
            return resultMap;
        } catch (Exception e) {

        }
        return null;
    }

    @Override
    public Boolean refund(Long orderId) {

        //获取支付记录
        PaymentInfo paymentInfo = paymentService.getPaymentInfo(orderId, PaymentTypeEnum.ALIPAY.getStatus());
        //添加信息到退款记录表
        RefundInfo refundInfo = refundInfoService.saveRefundInfo(paymentInfo);
        if (refundInfo.getRefundStatus().intValue() == RefundStatusEnum.REFUND.getStatus().intValue()) {
            return true;
        }
        //调用支付接口实现退款
        //封装需要参数
        AlipayClient alipayClient = new MyAlipayClient();
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        request.setNotifyUrl(ConstantPropertiesUtils.NOTIFY_URL);//支付回调
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", paymentInfo.getOutTradeNo());//设置你的订单号
        bizContent.put("trade_no", paymentInfo.getTradeNo());//设置支付宝交易号
        bizContent.put("refund_amount", paymentInfo.getTotalAmount());//设置金额
        request.setBizContent(bizContent.toString());
        AlipayTradeRefundResponse response;
        try {
            response = alipayClient.execute(request);
            if (response.isSuccess()) {
                refundInfo.setCallbackTime(new Date());
                refundInfo.setTradeNo(response.getTradeNo());
                refundInfo.setRefundStatus(RefundStatusEnum.REFUND.getStatus());
                refundInfo.setCallbackContent(JSONObject.toJSONString(response));
                refundInfoService.updateById(refundInfo);
                return true;
            }
            return false;
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
    }
}
